

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
import server from '@/utils/server'

export function parseTime (time, cFormat) {
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
      time = parseInt(time)
    }
    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay(),
  }
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    return value.toString().padStart(2, '0')
  })
  return time_str
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime (time, option) {
  if (('' + time).length === 10) {
    time = parseInt(time) * 1000
  } else {
    time = +time
  }
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    )
  }
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj (url) {
  const search = url.split('?')[1]
  if (!search) {
    return {}
  }
  return JSON.parse(
    '{"' +
    decodeURIComponent(search).
      replace(/"/g, '\\"').
      replace(/&/g, '","').
      replace(/=/g, '":"').
      replace(/\+/g, ' ') +
    '"}',
  )
}

export function makeUUID () {
  // xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx for 32位长度uuid
  // 'l' for leading letter
  var padding = 'lxxxxxxxxx'
  var baseResult = 36 // 36 or 16
  var d = new Date().getTime()
  if (window.performance && typeof window.performance.now === 'function') {
    // use high-precision timer if available
    d += performance.now()
  }

  var uuid = padding.replace(/[xyl]/g, function (c) {
    var base = c === 'l' ? (baseResult - 10) : baseResult
    var r = (d + Math.random() * base) % base | 0
    d = Math.floor(d / base)

    if (c === 'l') {
      r += 10
      return r.toString(baseResult)
    }

    return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(baseResult)
  })

  return uuid
}

/**
 * 数组或纯对象序列化
 * {a: 10, b: 'string'} => "10:a;string:b"
 *
 * @param   {Object/Array}  obj
 * @return  {String}        字符串
 *
 * @author  Neelie <h@pepm.com.cn>
 * @version v5.0
 */
export function zEncode (obj) {

}

export function zDecode (str) {

}

// todo: 不能像console.log体现代码文件和行数, 如何实现
export function log (str) {
  if (process.env.NODE_ENV === 'production') {
    return
  }

  if (typeof str !== 'object') {
    console.log(str)
    return
  }

  console.log(JSON.parse(JSON.stringify(str)))
}

export const dateFormat = (fmt = 'yyyy-MM-dd hh:mm:ss', date) => {
  if (typeof date !== 'object' || typeof date.getMonth !== 'function') {
    date = new Date()
  }

  var o = {
    'M+': date.getMonth() + 1, // 月份
    'd+': date.getDate(), // 日
    'h+': date.getHours(), // 小时
    'm+': date.getMinutes(), // 分
    's+': date.getSeconds(), // 秒
    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    'S': date.getMilliseconds() // 毫秒
  }
  if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1,
    (date.getFullYear() + '').substr(4 - RegExp.$1.length))
  for (var k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1,
      (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(
        ('' + o[k]).length)))
  }

  return fmt
}

export function paddingStr (str, paddingStr, length, left = false) {
  var s = str + ''
  const sLength = s.length
  if (sLength > length || paddingStr.toString().length < 1) {
    return s
  }

  const paddingChar = paddingStr.toString().charAt(0)
  for (var i = 0; i < (length - sLength); i++) {
    if (left) {
      s = paddingChar.concat(s)
    } else {
      s = s.concat(paddingChar)
    }
  }

  return s
}

export function numberFormat (
  number, decimals, dec_point, thousands_sep, padding) {
  number = (number + '').replace(/[^0-9+\-Ee.]/g, '')
  if (number === '') {
    return number
  }

  var n = !isFinite(+number) ? 0 : +number
  var prec = !isFinite(+decimals) ? 6 : Math.abs(decimals)
  var sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep
  var dec = (typeof dec_point === 'undefined') ? '.' : dec_point
  var padding = padding || false
  var s = ''
  var toFixedFix = function (n, prec) {
    var k = Math.pow(10, prec)
    return '' + Math.round(n * k) / k
  }
  // Fix for IE parseFloat(0.55).toFixed(0) = 0
  s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
  if (s[0].length > 3) {
    s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep)
  }

  if (padding) {
    s[1] = paddingStr((s[1] || ''), '0', decimals)
    return s.join(dec)
  } else {
    if (!s[1] && s[0] === '0') return '0'
  }
  return s.join(dec)
}

export function nl2br (str) {
  if (!str) {
    return ''
  }

  var breakTag = '<br>'
  return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag +
    '$2')
}

// 超轻量级模板渲染
export function tpl (s, d, clear) {
  for (var p in d) s = s.replace(new RegExp('{' + p + '}', 'g'), d[p])
  if (clear) {
    s = s.replace(new RegExp('{.*}', 'g'), '')
  }

  return s
}

// 文件名图片类型
export function isImage (name) {
  if (!name || typeof name !== 'string') {
    return false
  }

  const ext = name.substr(name.lastIndexOf('.') + 1)
  const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp']

  return imageTypes.indexOf(ext) !== -1
}

export function is_wx () {
  let ua = navigator.userAgent.toLowerCase()
  if (ua.match(/MicroMessenger/i) == 'micromessenger') {
    console.log('是微信')
    return true
  } else {
    console.log('不是是微信')
    return false
  }
}

export function isSso () {
  const host = window.location.host.toLowerCase()

  return host.indexOf('gptest.chec.bj.cn') !== -1 ||
    host.indexOf('gp.chec.bj.cn') !== -1
}

export function _isEmpty (input) {
  return input + '' === 'null' || input + '' === 'undefined' || input === ''
}

export function getParams (name) {

  return decodeURIComponent(
    (new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(
      location.href,
    ) || [, ''])[1].replace(/\+/g, '%20'),
  ) || null
}

export function getReferParames (name) {
  return decodeURIComponent(
    (new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(
      document.referrer,
    ) || [, ''])[1].replace(/\+/g, '%20'),
  ) || null
}

export function json_to_get (sstr) {
  sstr = sstr.replace(/\t/g, '')
  sstr = sstr.replace(/\"/g, '').replace('{', '').replace('}', '')
  sstr = sstr.replace(',', '&').replace(':', '=')
  sstr = sstr.replace(/\"/g, '').replace(/{/g, '').replace(/}/g, '')
  sstr = sstr.replace(/,/g, '&').replace(/:/g, '=')
  return sstr
}

/**
 * 表格时间格式化
 */
export function formatDate (cellValue) {
  if (cellValue == null || cellValue == '') return ''
  var date = new Date(cellValue)
  var year = date.getFullYear()
  var month = date.getMonth() + 1 < 10
    ? '0' + (date.getMonth() + 1)
    : date.getMonth() + 1
  var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
  var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
  var minutes = date.getMinutes() < 10
    ? '0' + date.getMinutes()
    : date.getMinutes()
  var seconds = date.getSeconds() < 10
    ? '0' + date.getSeconds()
    : date.getSeconds()
  return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' +
    seconds
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject (url) {
  url = url == null ? window.location.href : url
  const search = url.substring(url.lastIndexOf('?') + 1)
  const obj = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}

/**
 * @param {string} input value
 * @returns {number} output value
 */
export function byteLength (str) {
  // returns the byte length of an utf8 string
  let s = str.length
  for (var i = str.length - 1; i >= 0; i--) {
    const code = str.charCodeAt(i)
    if (code > 0x7f && code <= 0x7ff) s++
    else if (code > 0x7ff && code <= 0xffff) s += 2
    if (code >= 0xDC00 && code <= 0xDFFF) i--
  }
  return s
}

/**
 * @param {Array} actual
 * @returns {Array}
 */
export function cleanArray (actual) {
  const newArray = []
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i])
    }
  }
  return newArray
}

/**
 * @param {Object} json
 * @returns {Array}
 */
export function param (json) {
  if (!json) return ''
  return cleanArray(
    Object.keys(json).map(key => {
      if (json[key] === undefined) return ''
      return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
    }),
  ).join('&')
}

/**
 * @param {string} val
 * @returns {string}
 */
export function html2Text (val) {
  const div = document.createElement('div')
  div.innerHTML = val
  return div.textContent || div.innerText
}

/**
 * Merges two objects, giving the last one precedence
 * @param {Object} target
 * @param {(Object|Array)} source
 * @returns {Object}
 */
export function objectMerge (target, source) {
  if (typeof target !== 'object') {
    target = {}
  }
  if (Array.isArray(source)) {
    return source.slice()
  }
  Object.keys(source).forEach(property => {
    const sourceProperty = source[property]
    if (typeof sourceProperty === 'object') {
      target[property] = objectMerge(target[property], sourceProperty)
    } else {
      target[property] = sourceProperty
    }
  })
  return target
}

/**
 * @param {HTMLElement} element
 * @param {string} className
 */
export function toggleClass (element, className) {
  if (!element || !className) {
    return
  }
  let classString = element.className
  const nameIndex = classString.indexOf(className)
  if (nameIndex === -1) {
    classString += '' + className
  } else {
    classString =
      classString.substr(0, nameIndex) +
      classString.substr(nameIndex + className.length)
  }
  element.className = classString
}

/**
 * @param {string} type
 * @returns {Date}
 */
export function getTime (type) {
  if (type === 'start') {
    return new Date().getTime() - 3600 * 1000 * 24 * 90
  } else {
    return new Date(new Date().toDateString())
  }
}

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce (func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function () {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function (...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 * @param {Object} source
 * @returns {Object}
 */
export function deepClone (source) {
  return JSON.parse(JSON.stringify(source))
}

/**
 * @param {Array} arr
 * @returns {Array}
 */
export function uniqueArr (arr) {
  return Array.from(new Set(arr))
}

/**
 * @returns {string}
 */
export function createUniqueString () {
  const timestamp = +new Date() + ''
  const randomNum = parseInt((1 + Math.random()) * 65536) + ''
  return (+(randomNum + timestamp)).toString(32)
}

/**
 * Check if an element has a class
 * @param {HTMLElement} elm
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass (ele, cls) {
  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
}

/**
 * Add class to element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function addClass (ele, cls) {
  if (!hasClass(ele, cls)) ele.className += ' ' + cls
}

/**
 * Remove class from element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function removeClass (ele, cls) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
    ele.className = ele.className.replace(reg, ' ')
  }
}

export function makeMap (str, expectsLowerCase) {
  const map = Object.create(null)
  const list = str.split(',')
  for (let i = 0; i < list.length; i++) {
    map[list[i]] = true
  }
  return expectsLowerCase
    ? val => map[val.toLowerCase()]
    : val => map[val]
}

export const exportDefault = 'export default '

export const beautifierConf = {
  html: {
    indent_size: '2',
    indent_char: ' ',
    max_preserve_newlines: '-1',
    preserve_newlines: false,
    keep_array_indentation: false,
    break_chained_methods: false,
    indent_scripts: 'separate',
    brace_style: 'end-expand',
    space_before_conditional: true,
    unescape_strings: false,
    jslint_happy: false,
    end_with_newline: true,
    wrap_line_length: '110',
    indent_inner_html: true,
    comma_first: false,
    e4x: true,
    indent_empty_lines: true,
  },
  js: {
    indent_size: '2',
    indent_char: ' ',
    max_preserve_newlines: '-1',
    preserve_newlines: false,
    keep_array_indentation: false,
    break_chained_methods: false,
    indent_scripts: 'normal',
    brace_style: 'end-expand',
    space_before_conditional: true,
    unescape_strings: false,
    jslint_happy: true,
    end_with_newline: true,
    wrap_line_length: '110',
    indent_inner_html: true,
    comma_first: false,
    e4x: true,
    indent_empty_lines: true,
  },
}

// 首字母大小
export function titleCase (str) {
  return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
}

// 下划转驼峰
export function camelCase (str) {
  return str.replace(/-[a-z]/g, str1 => str1.substr(-1).toUpperCase())
}

export function isNumberStr (str) {
  return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
}

export function isJSON (str) {
  return !(typeof str === 'string')
}

export function isJSONStr (str) {
  if (typeof str === 'string') {
    try {
      JSON.parse(str)
      return true
    } catch (e) {
      return false
    }
  }
  return false
}

export function workflowUrl (data, pagetype = 'view') {
  const item = deepClone(data)

  item.uuid = item.uuid || ''
  if (!_isEmpty(item.entityData)) {
    item.uuid = item.entityData.uuid
  }

  const json = {
    workitemname: item.workitemname,
    participant: item.participant,
    workitemid: item.workitemid,
    workitemstate: item.workitemstate,
    processinststate: item.processinststate,
    endtime: item.endtime,
    processchname: item.processchname,
    processinstname: item.processinstname,
    processinstid: item.processinstid,
    participantid: item.participantid,
    rollbackflag: item.rollbackflag,
    activityinstid: item.activityinstid,
    starttime: item.starttime,
    processdefid: item.processdefid,
    processdefname: item.processdefname,
    actionurl: item.actionurl,
    activitydefid: item.activitydefid,
    activityinstname: item.activityinstname,
    uuid: item.uuid,
  }

  const tempwindow = window.open()
  const local = window.location.hostname === 'localhost'
    ? 'https://gptest.chec.bj.cn/default_im/'
    : ''
  const newurl = `${local}default${json.actionurl}?page_type=` + pagetype +
    `&uuid=${item.uuid}&dataUrl=${encodeURIComponent(
      JSON.stringify(json),
    )}&${json_to_get(JSON.stringify(json))}`
  tempwindow.location.href = newurl
}

export function workflowItem (item, position) {
  if (_isEmpty(item.wfWorkItemVoList)) {
    return
  }

  let uuid = ''
  if (!_isEmpty(item.entityData)) {
    uuid = item.entityData.uuid
  }

  const workflows = deepClone(item.wfWorkItemVoList)
  if (position === 'first') {
    workflows[0].uuid = uuid
    return workflows[0]
  }

  if (position === 'last') {
    const pos = workflows.length - 1
    workflows[pos].uuid = uuid
    return workflows[pos]
  }

  // 返回可能的当前节点
  const {dbId} = server.getUserInfo()
  for (var i = workflows.length - 1; i >= 0; i--) {
    const state = workflows[i].workitemstate

    if ([4, 8, 10].indexOf(state) !== -1 &&
      parseInt(workflows[i].participantid) === dbId) {
      workflows[i].uuid = uuid
      return workflows[i]
    }

    if ([0, 12, 13].indexOf(state) !== -1) {
      workflows[i].uuid = uuid
      return workflows[i]
    }
  }

  workflows[0].uuid = uuid
  return workflows[0]
}

export function doneUrl (data) {
  let item = deepClone(data)

  item.current = {}
  item.uuid = ''
  if (!_isEmpty(item.processData) &&
    !_isEmpty(item.processData.wfWorkItemVoList)) {
    item.processData.wfWorkItemVoList.forEach(wf => {
      if (parseInt(wf.workitemstate) === 12 ||
        parseInt(wf.workitemstate) === 13) {
        item.current = wf
      }
    })
  }
  if (!_isEmpty(item.current) && !_isEmpty(item.current.actionurl)) {
    item.current.uuid = item.uuid
    item = item.current
  }

  const json = {
    workitemname: item.workitemname,
    participant: item.participant,
    workitemid: item.workitemid,
    workitemstate: item.workitemstate,
    processinststate: item.processinststate,
    endtime: item.endtime,
    processchname: item.processchname,
    processinstname: item.processinstname,
    processinstid: item.processinstid,
    participantid: item.participantid,
    rollbackflag: item.rollbackflag,
    activityinstid: item.activityinstid,
    starttime: item.starttime,
    processdefid: item.processdefid,
    processdefname: item.processdefname,
    actionurl: item.actionurl,
    activitydefid: item.activitydefid,
    activityinstname: item.activityinstname,
    uuid: item.uuid,
  }
  const tempwindow = window.open()
  const local = window.location.hostname === 'localhost'
    ? 'http://10.2.98.197/'
    : ''
  const newurl = `${local}default${json.actionurl}?uuid=${item.uuid}&processinstid=${item.processinstid}&activityinstid=${item.activityinstid}&dataUrl=${encodeURIComponent(
    JSON.stringify(json),
  )}`
  tempwindow.location.href = newurl
}

export function rem () {
  let docEl = document.documentElement,
    resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'
  let clientWidth = docEl.clientWidth
  if (!clientWidth) return
  if (clientWidth >= 1920) {
    docEl.style.fontSize = '100px' //1rem  = 100px
  } else {
    docEl.style.fontSize = 100 * (clientWidth / 1920) + 'px'
  }
  let recalc = function () {
    let clientWidth = docEl.clientWidth;
    if (!clientWidth) return;
    if (clientWidth >= 1920) {
      docEl.style.fontSize = '100px'; //1rem  = 100px
    } else {
      docEl.style.fontSize = 100 * (clientWidth / 1920) + 'px';
    }
  };
  if (!document.addEventListener) return;
  window.addEventListener(resizeEvt, recalc, false);
  document.addEventListener('DOMContentLoaded', recalc, false);
}

export function checkPhone(phone){
  if(!(/^1(3|4|5|6|7|8|9)\d{9}$/.test(phone))){
    return false;
  }
  return true
}
